package com.icode.web.validator;

import com.icode.core.dto.user.CityDTO;
import com.icode.core.dto.user.DistrictDTO;
import com.icode.core.dto.user.ProvinceDTO;
import com.icode.core.dto.user.UsersInfoDTO;
import com.icode.core.model.user.City;
import com.icode.core.model.user.District;
import com.icode.core.model.user.Province;
import com.icode.core.model.user.UserInfo;
import com.icode.service.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 * User: xianfei
 * Date: 15-1-8
 * Time: 下午3:29
 * To change this template use File | Settings | File Templates.
 */
@Component
public class UsersInfoFormValidator implements Validator {

    @Autowired
    private UserService userService;

    @Override
    public boolean supports(Class<?> clazz) {
        return UsersInfoDTO.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        UsersInfoDTO usersInfoDTO = (UsersInfoDTO) target;
        String username = usersInfoDTO.getUsername();
        String realName = usersInfoDTO.getRealName();
        String birthday = usersInfoDTO.getBirthday();
        String IDCard = usersInfoDTO.getIDCard();
        String email = usersInfoDTO.getEmail();
        String province = usersInfoDTO.getProvince();
        String city = usersInfoDTO.getCity();
        String district = usersInfoDTO.getDistrict();
        String area = usersInfoDTO.getArea();
        MultipartFile image = usersInfoDTO.getUsersInfoImage();

        if (!isSelect(province) || !isSelect(city) || !isSelect(district) || "".equals(area)) {
            errors.rejectValue("area", null, "请选择地区!");
            List<Province> provinces = userService.findProvince();
            usersInfoDTO.setProvinces(ProvinceDTO.toDTOs(provinces));
            return;
        }

        List<Province> provinces = userService.findProvince();
        List<City> cities = userService.findCityById(usersInfoDTO.getProvince());
        List<District> districts = userService.findDistrictById(usersInfoDTO.getCity());
        usersInfoDTO.initAddress(ProvinceDTO.toDTOs(provinces), CityDTO.toDTOs(cities), DistrictDTO.toDTOs(districts));

        if (!isExistUsername(username)) {
            errors.rejectValue("username", null, "用户名已被使用!");
        }
//        if (!Pattern.matches("[\u4E00-\u9FA5]*", realName)) {
//            errors.rejectValue("realName", null, "不能有非法字符");
//        }
        if (Pattern.matches("[\\d]{17}[\\w]{1}|[\\d]{15}", IDCard)) {
            if (Pattern.matches("[\\d]{17}[\\w]{1}", IDCard)) {
                if (!idCardValidate(IDCard)) {
                    errors.rejectValue("IDCard", null, "身份证不合法!");
                }
            }
            if (!isIDCard(IDCard, birthday)) {
                errors.rejectValue("IDCard", null, "身份证与生日不相符!");
            }
        } else {
            errors.rejectValue("IDCard", null, "身份证不合法!");
        }
        if (!Pattern.matches("[\\w[\\.-]]+@[\\w]+\\.com", email)) {
            errors.rejectValue("email", null, "邮箱不合法!");
        }
        if (!imgIsNull(image)) {
            if (!isImages(image)) {
                errors.rejectValue("usersInfoImage", null, "图片格式不正确!");
            }
            if (image.getSize() > 5120000) {
                errors.rejectValue("usersInfoImage", null, "图片不能超过5M!");
            }
        }


    }


    private boolean isImages(MultipartFile image) {
        if (isEquals(image.getOriginalFilename())) {
            return true;
        }
        return false;
    }

    private boolean isEquals(String fileName) {
        String[] file = fileName.split("\\.");
        String[] fileType = {"jpg", "png", "psd", "jpeg", "gif"};
        for (String type : fileType) {
            if (type.equalsIgnoreCase(file[1])) {
                return true;
            }
        }
        return false;
    }

    private boolean isExistUsername(String username) {
        List<UserInfo> usersInfo = userService.findUsersInfoByUsername(username);
        if (usersInfo.size() <= 1) {
            return true;
        }
        return false;
    }

    private boolean imgIsNull(MultipartFile image) {
        if ("".equalsIgnoreCase(image.getOriginalFilename())) {
            return true;
        }
        return false;
    }

    private boolean isIDCard(String IDCard, String birthday) {
        String[] birthdays = birthday.split("-");
        String b = "";
        for (int i = 0; i < birthdays.length; i++) {
            b += birthdays[i];
        }
        if (b.equals(IDCard.substring(6, 14))) {
            return true;
        }
        return false;
    }

    private boolean isSelect(String address) {
        if ("noselect".equals(address)) {
            return false;
        }
        return true;
    }

    private boolean idCardValidate(String idCard) {
        String num = lastNum(idCard);
        if (num.equals(idCard.substring(17))) {
            return true;
        }
        return false;
    }

    private String lastNum(String idCard) {
        String result = "";
        String str = idCard.substring(0, 17);
        char[] array = str.toCharArray();
        int[] data = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        int sum = 0;
        for (int i = 0; i < array.length; i++) {
            sum += Integer.parseInt(array[i] + "") * data[i];
        }
        int a = sum % 11;
        switch (a) {
            case 0:
                result = "1";
                break;
            case 1:
                result = "0";
                break;
            case 2:
                result = "x";
                break;
            case 3:
                result = "9";
                break;
            case 4:
                result = "8";
                break;
            case 5:
                result = "7";
                break;
            case 6:
                result = "6";
                break;
            case 7:
                result = "5";
                break;
            case 8:
                result = "4";
                break;
            case 9:
                result = "3";
                break;
            case 10:
                result = "2";
                break;
        }
        return result;
    }


}
